package com.stylefeng.guns.modular.pay.service.impl;

import static com.baidu.unbiz.fluentvalidator.ResultCollectors.toSimple;

import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;

import javax.validation.Validation;
import javax.validation.Validator;
import javax.validation.ValidatorFactory;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baidu.unbiz.fluentvalidator.FluentValidator;
import com.baidu.unbiz.fluentvalidator.Result;
import com.baidu.unbiz.fluentvalidator.jsr303.HibernateSupportedValidator;
import com.google.common.base.Strings;
import com.google.gson.Gson;
import com.stylefeng.guns.config.properties.PayProperties;
import com.stylefeng.guns.core.util.HttpUtils;
import com.stylefeng.guns.core.util.JsonUtils;
import com.stylefeng.guns.core.util.MD5Utils;
import com.stylefeng.guns.core.util.ObjectUtils;
import com.stylefeng.guns.modular.pay.exception.BusException;
import com.stylefeng.guns.modular.pay.exception.ResultEnum;
import com.stylefeng.guns.modular.pay.model.MchBus;
import com.stylefeng.guns.modular.pay.model.MchInfo;
import com.stylefeng.guns.modular.pay.model.MchReg;
import com.stylefeng.guns.modular.pay.model.Trans;
import com.stylefeng.guns.modular.pay.payment.jft.api.ApiBankCardModifyRequest;
import com.stylefeng.guns.modular.pay.payment.jft.api.ApiJftPayQueryRequest;
import com.stylefeng.guns.modular.pay.payment.jft.api.ApiJftQuickPayRequst;
import com.stylefeng.guns.modular.pay.payment.jft.api.ApiMemberBusRequest;
import com.stylefeng.guns.modular.pay.payment.jft.api.ApiMemberBusRsponse;
import com.stylefeng.guns.modular.pay.payment.jft.api.ApiMemberRegRequest;
import com.stylefeng.guns.modular.pay.payment.jft.api.ApiMemberRegRsponse;
import com.stylefeng.guns.modular.pay.payment.jft.api.ApiNotifyRsponse;
import com.stylefeng.guns.modular.pay.payment.jft.api.ApiQuickPayQueryRsponse;
import com.stylefeng.guns.modular.pay.payment.jft.api.ApiQuickPayRsponse;
import com.stylefeng.guns.modular.pay.payment.jft.common.JftConfigure;
import com.stylefeng.guns.modular.pay.payment.jft.core.AESUtil;
import com.stylefeng.guns.modular.pay.payment.jft.core.MD5Util;
import com.stylefeng.guns.modular.pay.payment.jft.request.QuickPay;
import com.stylefeng.guns.modular.pay.service.IAccountService;
import com.stylefeng.guns.modular.pay.service.IJftPayService;
import com.stylefeng.guns.modular.pay.service.IMchBusService;
import com.stylefeng.guns.modular.pay.service.IMchInfoService;
import com.stylefeng.guns.modular.pay.service.IMchRegService;
import com.stylefeng.guns.modular.pay.service.ITransService;
import com.stylefeng.guns.modular.pay.validator.MchRouterValidator;
import com.stylefeng.guns.modular.pay.validator.SignVerifyValidator;
/**
 * 佳付通业务接口实现
 * @author Administrator
 *
 */
@Service
public class JftPayServiceImpl implements IJftPayService {
    private final static Logger logger = LoggerFactory.getLogger(JftPayServiceImpl.class);

	private static Validator validator;
	@Autowired
	private IMchInfoService mchInfoService;
	@Autowired
	private SignVerifyValidator signVerifyValidator;
	@Autowired
	private MchRouterValidator mchRouterValidator;
	@Autowired
	private ITransService transService;
	@Autowired
	private IMchRegService mchRegService;
	@Autowired
	private IdWorkerService idWorkerService;
	@Autowired
	private IMchBusService mchBusService;
	@Autowired
	private PayProperties payProperties;
	@Autowired
	private IAccountService accountService;
	

	static {
		Locale.setDefault(Locale.ENGLISH); // speicify language
		ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
		validator = factory.getValidator();
	}

	@Override
	public Object quickPay(Map<String, String> params) {
		ApiQuickPayRsponse response = new ApiQuickPayRsponse();
		ApiJftQuickPayRequst req = new Gson().fromJson(JsonUtils.mapToJson(params), ApiJftQuickPayRequst.class);
		MchInfo mch = mchInfoService.findByMchNo(req.getMchNo());
		if(mch==null){
			throw new BusException(ResultEnum.MCH_UNREGISTER,"");
		}
		String key = mch.getMd5Key();
		//业务校验
		Result ret = FluentValidator.checkAll()
				.on(req, new HibernateSupportedValidator<ApiJftQuickPayRequst>().setHiberanteValidator(validator))
				.on(params, signVerifyValidator) // 验签
				.on("JFT_QUICK", mchRouterValidator) // 验签
				.doValidate().result(toSimple());
		if (!ret.isSuccess()) {
			String msg = ret.getErrors().get(0);
			throw new BusException(ResultEnum.ERROR_VALIDATE, msg,key);
		}
		Trans trans = transService.findByMchNoAndOrderCode(req.getMchNo(),req.getOrderCode());
		if(trans!=null){
			throw new BusException(ResultEnum.ORDER_REPEAT, key);
		}
		MchReg mchReg = mchRegService.findByChMerCode(req.getChMerCode());
		if(mchReg==null){
			throw new BusException(ResultEnum.MCH_UNAPPLICATION,key);
		}
		if(mchReg!=null &&mchReg.getStatus()!=1 ){
			throw new BusException(ResultEnum.MCH_APPLICATION_UNSUCCESS,key);
		}
		//验证业务是否开通
		MchBus bus = mchBusService.findBychMerCode(mchReg.getChMerCode());
		if(bus==null || bus.getStatus()!=1){
			throw new BusException(ResultEnum.MCHBUS_UNOPEN,key);
		}
		String platOrderCode = idWorkerService.idGenerator();
		// 创建支付流水
		trans = new Trans();
		trans.setMchNo(mch.getMchNo());
		trans.setMchName(mch.getMchNickName());
		trans.setPlatOrderCode(platOrderCode);
		trans.setMerCode(mchReg.getChMerCode());
		createTrans(trans, req,bus);
		//构建请求参数
		QuickPay requset = null;
		try {
			String jftNotifyUrl = JftConfigure.JFTNOTIFYURL;
			String jftReturnUrl = JftConfigure.JFTRETURNURL;
			requset = new QuickPay(req,platOrderCode,jftNotifyUrl,jftReturnUrl);
			requset.setChMerCode(mchReg.getChMerCode());
		} catch (Exception e) {
			throw new BusException(ResultEnum.UNKONW_EXCEPTION,key);
		}
		Map<String,String> dataMap = new HashMap<String,String>();
		String resStr = "";
		try {
			String encryptDate = JsonUtils.mapToJson(ObjectUtils.Obj2Map(requset));
			byte[] encrypt = AESUtil.encryptAES(encryptDate.getBytes(), JftConfigure.AES_KEY.getBytes(), true, "UTF-8");
			dataMap.put("orgCode", JftConfigure.ORG_CODE);
			dataMap.put("encryptData", new String(encrypt,"UTF-8"));
			String linkString = MD5Utils.createLinkString(ObjectUtils.Obj2Map(requset)); 
			String sign = MD5Util.encrypt(linkString+"&md5key="+JftConfigure.MD5_KEY, "UTF-8");
			dataMap.put("signData", sign);
			resStr = HttpUtils.post(JftConfigure.BASE_URL+"/fusionPosp/interface/quickPay", dataMap);
		} catch (Exception e2) {
			throw new BusException(ResultEnum.UNKONW_EXCEPTION,key);
		}
		logger.info("resStr="+resStr);
		if(Strings.isNullOrEmpty(resStr)){
			throw new BusException(ResultEnum.CHANNEL_RESPONSE_ERROR,key);
		}
		JSONObject jsonObject = JSON.parseObject(resStr);
		if(jsonObject.containsKey("resCode")&& !"0000".equals(jsonObject.getString("resCode"))){
			String resCode = jsonObject.getString("resCode");
			String resMsg = jsonObject.getString("resMsg");
			transService.update(trans.getId(),2,resCode,resMsg);
			logger.info("渠道响应：resCode={}|resMsg={}",resCode,resMsg);
			throw new BusException(ResultEnum.RESPONSE_ERROR,resMsg,key);
		}
		String encryptData = jsonObject.getString("encryptData");
		JSONObject resObject = null;
		try {
			byte[] resDate = AESUtil.decryptAES(encryptData.getBytes(), JftConfigure.AES_KEY.getBytes(), true, "UTF-8");
			resObject = JSON.parseObject(new String(resDate,"UTF-8"));
		} catch (Exception e) {
			throw new BusException(ResultEnum.UNKONW_EXCEPTION,key);
		}
		logger.info("resObject="+resObject.toJSONString());
		String resCode = resObject.getString("resCode");
		String resMsg = resObject.getString("resMsg");
		if("0000".equals(resCode)){
			response = buildResponse(resObject);
		}else{
			response = buildResponse(resObject);
			transService.update(trans.getId(),2,resCode,resMsg);
		}
		try {
			response.setSign(MD5Utils.getSign(ObjectUtils.Obj2Map(response),  key));
		} catch (Exception e) {
			throw new BusException(ResultEnum.UNKONW_EXCEPTION,key);
		}
		return response;
	}


	private ApiQuickPayRsponse buildResponse(JSONObject resObject) {
		ApiQuickPayRsponse response = new ApiQuickPayRsponse();
		String resCode = resObject.getString("resCode");
		if("0000".equals(resCode)){
			response.setRespCode(resObject.getString("resCode"));
			response.setRespMsg(resObject.getString("resMsg"));
			response.setChMerCode(resObject.getString("chMerCode"));
			response.setChSerialNo(resObject.getString("chSerialNo"));
			response.setResultType(resObject.getString("resultType"));
			if("url_address".equals(resObject.getString("resultType"))){
				response.setUrl(resObject.getString("url"));
			}else if("html_text".equals(resObject.getString("resultType"))){
				response.setHtml(resObject.getString("html"));
			}
			response.setTranStatus(resObject.getString("tranStatus"));
			response.setTranTime(resObject.getString("tranTime"));
			response.setTranAmount(resObject.getString("tranAmount"));
		}else{
			response.setRespCode(resObject.getString("resCode"));
			response.setRespMsg(resObject.getString("resMsg"));
		}
		return response;
	}


	private Trans createTrans(Trans trans, ApiJftQuickPayRequst req,MchBus bus) {
		BigDecimal amount = new BigDecimal(req.getOrderAmount());
		trans.setMerCode("");
		trans.setChMerCode(req.getChMerCode());
		trans.setOrderCode(req.getOrderCode());
		trans.setOrderTime(req.getOrderTime());
		trans.setOrderAmount(amount);
		trans.setSettleType(0);
		trans.setBusCode(req.getBusCode());
		trans.setRealName(req.getRealName());
		trans.setIdCard(req.getIdCard());
		trans.setAccNo(req.getAccNo());
		trans.setMobile(req.getMobile());
		trans.setFrontUrl(req.getFrontUrl());
		trans.setCallBackUrl(req.getCallBackUrl());
		trans.setDrawFee(bus.getDrawFee());
		trans.setTradeRate(bus.getTradeRate());
		BigDecimal tradeFee = new BigDecimal(req.getOrderAmount()).multiply(bus.getTradeRate());
		trans.setTradeFee(tradeFee);
		trans.setActualAmount(amount.subtract(tradeFee).subtract(bus.getDrawFee()));
		trans.setTranStatus(3);
		trans.setCreateTime(new Date());
		transService.insert(trans);
		return trans;
	
	}

	@Override
	public Object memberReg(Map<String, String> params) {
		ApiMemberRegRsponse response = new ApiMemberRegRsponse();
		ApiMemberRegRequest req = new Gson().fromJson(JsonUtils.mapToJson(params), ApiMemberRegRequest.class);
		MchInfo mch = mchInfoService.findByMchNo(req.getMchNo());
		if(mch==null){
			throw new BusException(ResultEnum.MCH_UNREGISTER,"");
		}
		String key = mch.getMd5Key();
		Result ret = FluentValidator.checkAll()
				.on(req, new HibernateSupportedValidator<ApiMemberRegRequest>().setHiberanteValidator(validator))
				.on(params, signVerifyValidator) // 验签
				.doValidate().result(toSimple());
		if (!ret.isSuccess()) {
			String msg = ret.getErrors().get(0);
			throw new BusException(ResultEnum.ERROR_VALIDATE, msg,key);
		}
		//商户信息获取
		MchReg mchReg = mchRegService.findByMchNoAndMerCode(req.getMchNo(),req.getMerCode());
		if(mchReg!=null && mchReg.getStatus()==1){
			throw new BusException(ResultEnum.MCH_REPEAT_REGISTER,key);
		}
		String merCode = idWorkerService.idGenerator();
		if(mchReg==null){
			mchReg = createMchReg(merCode,req);
		}else{
			mchReg = updateMchReg(mchReg,req);
		}
		//请求参数封装
		Map<String,String> dataMap = new HashMap<String,String>();
		dataMap.put("orgCode", JftConfigure.ORG_CODE);
		String resStr = "";
		try {
			Map<String,String> mchMap = reqMap(req);
			String linkString = MD5Utils.createLinkString(mchMap); 
			String sign = MD5Util.encrypt(linkString+"&md5key="+JftConfigure.MD5_KEY, "UTF-8");
			byte[] encrypt = AESUtil.encryptAES(JsonUtils.mapToJson(mchMap).getBytes(), JftConfigure.AES_KEY.getBytes(), true, "UTF-8");
			dataMap.put("encryptData", new String(encrypt,"UTF-8"));
			dataMap.put("signData", sign);
			resStr = HttpUtils.post(JftConfigure.BASE_URL+"/fusionPosp/interface/memberReg", dataMap);
		} catch (Exception e2) {
			throw new BusException(ResultEnum.UNKONW_EXCEPTION,key);
		}
		logger.info("resStr="+resStr);
		if(Strings.isNullOrEmpty(resStr)){
			throw new BusException("channel.unkonw.exception","未知异常");
		}
		JSONObject jsonObject = JSON.parseObject(resStr);
		if(jsonObject.containsKey("resCode")&& !"0000".equals(jsonObject.getString("resCode"))){
			String resCode = jsonObject.getString("resCode");
			String resMsg = jsonObject.getString("resMsg");
			mchRegService.update(mchReg.getId(),2,resCode,resMsg);
			logger.info("渠道响应：resCode={}|resMsg={}",resCode,resMsg);
			throw new BusException(ResultEnum.CHANNEL_RESPONSE_ERROR, resMsg,key);
		}
		JSONObject resObject = null;
		String encryptData = jsonObject.getString("encryptData");
		try {
			byte[] resDate = AESUtil.decryptAES(encryptData.getBytes(), JftConfigure.AES_KEY.getBytes(), true, "UTF-8");
			resObject = JSON.parseObject(new String(resDate,"UTF-8"));
		} catch (Exception e) {
			throw new BusException(ResultEnum.UNKONW_EXCEPTION,key);
		}
		logger.info("resObject="+resObject.toJSONString());
		String resCode = resObject.getString("resCode");
		String resMsg = resObject.getString("resMsg");
		if("0000".equals(resCode)){
			String chMerCode = resObject.getString("chMerCode");
			mchRegService.update(mchReg.getId(),1,chMerCode,resCode,resMsg);
			response.setChMerCode(chMerCode);
		}else{
			mchRegService.update(mchReg.getId(),2,resCode,resMsg);
		}
		response.setRespCode(resCode);
		response.setRespMsg(resMsg);	
		try {
			response.setSign(MD5Utils.getSign(ObjectUtils.Obj2Map(response), key));
		} catch (Exception e) {
			throw new BusException(ResultEnum.UNKONW_EXCEPTION,key);
		}
		return response;
	}

	private Map<String, String> reqMap(ApiMemberRegRequest req) {
		Map<String,String> mchMap = new HashMap<String,String>();
		mchMap.put("verCode", "1001");
		mchMap.put("merCode", req.getMerCode());
		mchMap.put("merName", req.getMerName());
		mchMap.put("realName", req.getRealName());
		if(!Strings.isNullOrEmpty(req.getProvinceCode())){
			mchMap.put("provinceCode", req.getProvinceCode());
		}
		if(!Strings.isNullOrEmpty(req.getCityCode())){
			mchMap.put("cityCode", req.getCityCode());
		}
		if(!Strings.isNullOrEmpty(req.getMerAddress())){
			mchMap.put("merAddress", req.getMerAddress());	
		}
		mchMap.put("idCard", req.getIdCard());
		mchMap.put("mobile", req.getMobile());
		mchMap.put("accountName", req.getAccountName());
		mchMap.put("accountNo", req.getAccountNo());
		mchMap.put("reservedMobile", req.getReservedMobile());
		if(!Strings.isNullOrEmpty(req.getBankName())){
			mchMap.put("bankName", req.getBankName());
		}
		if(!Strings.isNullOrEmpty(req.getBankCode())){
			mchMap.put("bankCode", req.getBankCode());
		}
		if(!Strings.isNullOrEmpty(req.getOpenProvince())){
			mchMap.put("openProvince", req.getOpenProvince());
		}
		if(!Strings.isNullOrEmpty(req.getOpenCity())){
			mchMap.put("openCity", req.getOpenCity());
		}
		mchMap.put("subBankCode", req.getSubBankCode());
		return mchMap;
	}


	private MchReg updateMchReg(MchReg reg, ApiMemberRegRequest req) {
		reg.setAccountName(req.getAccountName());
		reg.setAccountNo(req.getAccountNo());
		reg.setBankCode(req.getBankCode());	
		reg.setBankName(req.getBankName());
		reg.setSubBankCode(req.getBankCode());
		reg.setCityCode(req.getCityCode());
		reg.setIdCard(req.getIdCard());
		reg.setMerAddress(req.getMerAddress());
		reg.setMerCode(req.getMerCode());
		reg.setMerName(req.getMerName());
		reg.setMobile(req.getMobile());
		reg.setOpenCity(req.getOpenCity());
		reg.setOpenProvince(req.getOpenProvince());
		reg.setProvinceCode(req.getProvinceCode());
		reg.setRealName(req.getRealName());
		reg.setReservedMobile(req.getReservedMobile());
		reg.setSubBankCode(req.getSubBankCode());	
		reg.setStatus(0);
		mchRegService.updateById(reg);
		return reg;
	}


	private MchReg createMchReg(String merCode, ApiMemberRegRequest req) {
		MchReg reg = new MchReg();
		reg.setMerCode(req.getMerCode());
		reg.setMchNo(req.getMchNo());
		reg.setPlatMerCode(merCode);
		reg.setAccountName(req.getAccountName());
		reg.setAccountNo(req.getAccountNo());
		reg.setBankCode(req.getBankCode());	
		reg.setBankName(req.getBankName());
		reg.setSubBankCode(req.getBankCode());
		reg.setCityCode(req.getCityCode());
		reg.setIdCard(req.getIdCard());
		reg.setMerAddress(req.getMerAddress());
		reg.setMerCode(req.getMerCode());
		reg.setMerName(req.getMerName());
		reg.setMobile(req.getMobile());
		reg.setOpenCity(req.getOpenCity());
		reg.setOpenProvince(req.getOpenProvince());
		reg.setProvinceCode(req.getProvinceCode());
		reg.setRealName(req.getRealName());
		reg.setReservedMobile(req.getReservedMobile());
		reg.setSubBankCode(req.getSubBankCode());	
		reg.setStatus(0);
		mchRegService.insert(reg);
		return reg;
	}


	@Override
	public Object memberBus(Map<String, String> params) {
		ApiMemberBusRsponse response = new ApiMemberBusRsponse();
		ApiMemberBusRequest req = new Gson().fromJson(JsonUtils.mapToJson(params), ApiMemberBusRequest.class);
		MchInfo mch = mchInfoService.findByMchNo(req.getMchNo());
		if(mch==null){
			throw new BusException(ResultEnum.MCH_UNREGISTER,"");
		}
		String key = mch.getMd5Key();
		
		Result ret = FluentValidator.checkAll()
				.on(req, new HibernateSupportedValidator<ApiMemberBusRequest>().setHiberanteValidator(validator))
				.on(params, signVerifyValidator) // 验签
				.doValidate().result(toSimple());
		if (!ret.isSuccess()) {
			String msg = ret.getErrors().get(0);
			throw new BusException("error.validate", msg);
		}
		MchReg mchReg = mchRegService.findByChMerCode(req.getChMerCode());
		if(mchReg==null){
			throw new BusException(ResultEnum.MCH_UNAPPLICATION,key);
		}
		if(mchReg!=null && mchReg.getStatus()!=1){//开通成功
			throw new BusException(ResultEnum.MCH_APPLICATION_UNSUCCESS,key);
		}
		MchBus bus = mchBusService.findBychMerCode(req.getChMerCode());
		if(bus!=null && bus.getStatus()==1){
			throw new BusException(ResultEnum.MCH_BUS_REPEAT,key);
		}
		if(bus!=null){
			bus.setBusCode(req.getBusCode());
			bus.setChMerCode(req.getChMerCode());
			bus.setDrawFee(new BigDecimal(req.getDrawFee()));
			bus.setMerCode(req.getChMerCode());
			bus.setTradeRate(new BigDecimal(req.getTradeRate()));
			bus.setStatus(0);
			mchBusService.updateById(bus);
		}else{
			bus = new MchBus();
			bus.setBusCode(req.getBusCode());
			bus.setChMerCode(req.getChMerCode());
			bus.setDrawFee(new BigDecimal(req.getDrawFee()));
			bus.setMerCode(req.getChMerCode());
			bus.setTradeRate(new BigDecimal(req.getTradeRate()));
			bus.setStatus(0);
			mchBusService.insert(bus);
		}
		//请求渠道
		Map<String,String> reqMap = new HashMap<String,String>();
		reqMap.put("verCode", "1001");
		reqMap.put("chMerCode", req.getChMerCode());
		reqMap.put("busCode", req.getBusCode());
		reqMap.put("drawFee", req.getDrawFee());
		reqMap.put("tradeRate", req.getTradeRate());
		Map<String,String> dataMap = new HashMap<String,String>();
		String resStr = "";
		try {
			String linkString = MD5Utils.createLinkString(reqMap); 
			String sign = MD5Util.encrypt(linkString+"&md5key="+JftConfigure.MD5_KEY, "UTF-8");
			byte[] encrypt = AESUtil.encryptAES(JsonUtils.mapToJson(reqMap).getBytes(), JftConfigure.AES_KEY.getBytes(), true, "UTF-8");
			
			dataMap.put("encryptData", new String(encrypt,"UTF-8"));
			dataMap.put("orgCode", JftConfigure.ORG_CODE);
			dataMap.put("signData", sign);
			resStr = HttpUtils.post(JftConfigure.BASE_URL+"/fusionPosp/interface/memberBus", dataMap);
		} catch (Exception e2) {
			throw new BusException(ResultEnum.UNKONW_EXCEPTION,key);
		}
		if(Strings.isNullOrEmpty(resStr)){
			throw new BusException(ResultEnum.CHANNEL_RESPONSE_ERROR,key);
		}
		logger.info("resStr="+resStr);//{"resCode":"0015","resMsg":"签名错误"}
		JSONObject jsonObject = JSON.parseObject(resStr);
		if(jsonObject.containsKey("resCode")&& !"0000".equals(jsonObject.getString("resCode"))){
			String resCode = jsonObject.getString("resCode");
			String resMsg = jsonObject.getString("resMsg");
			mchBusService.update(bus.getId(),2,resCode,resMsg);
			logger.info("渠道响应：resCode={}|resMsg={}",resCode,resMsg);
			throw new BusException(ResultEnum.CHANNEL_RESPONSE_ERROR, resMsg,key);
		}
		JSONObject resObject = null;
		String encryptData = jsonObject.getString("encryptData");
		try {
			byte[] resDate = AESUtil.decryptAES(encryptData.getBytes(), JftConfigure.AES_KEY.getBytes(), true, "UTF-8");
			resObject = JSON.parseObject(new String(resDate,"UTF-8"));
		} catch (Exception e) {
			throw new BusException(ResultEnum.UNKONW_EXCEPTION,key);
		}
		logger.info("resObject="+resObject.toJSONString());
		String resCode = resObject.getString("resCode");
		String resMsg = resObject.getString("resMsg");
		if("0000".equals(resCode)){
			mchBusService.update(bus.getId(), 1, resCode, resMsg);
			response.setChMerCode(resObject.getString("chMerCode"));
		}else{
			mchBusService.update(bus.getId(),2,resCode,resMsg);
		}
		response.setRespCode(resCode);
		response.setRespMsg(resMsg);	
		try {
			response.setSign(MD5Utils.getSign(ObjectUtils.Obj2Map(response), key));
		} catch (Exception e) {
			throw new BusException(ResultEnum.UNKONW_EXCEPTION,key);
		}
		return response;
	}

	@Override
	public Object rateModify(Map<String, String> params) {
		ApiMemberBusRsponse response = new ApiMemberBusRsponse();
		ApiMemberBusRequest req = new Gson().fromJson(JsonUtils.mapToJson(params), ApiMemberBusRequest.class);
		MchInfo mch = mchInfoService.findByMchNo(req.getMchNo());
		if(mch==null){
			throw new BusException(ResultEnum.MCH_UNREGISTER,"");
		}
		String key = mch.getMd5Key();
		Result ret = FluentValidator.checkAll()
				.on(req, new HibernateSupportedValidator<ApiMemberBusRequest>().setHiberanteValidator(validator))
				.on(params, signVerifyValidator) // 验签
				.doValidate().result(toSimple());
		if (!ret.isSuccess()) {
			String msg = ret.getErrors().get(0);
			throw new BusException("error.validate", msg);
		}
		//商户信息获取
		MchBus bus = mchBusService.findBychMerCode(req.getChMerCode());
		if(bus==null || bus.getStatus()!=1){
			throw new BusException(ResultEnum.MCH_APPLICATION_UNSUCCESS,key);
		}
		//请求渠道
		Map<String,String> reqMap = new HashMap<String,String>();
		reqMap.put("verCode", "1001");
		reqMap.put("chMerCode", req.getChMerCode());
		reqMap.put("busCode", req.getBusCode());
		reqMap.put("drawFee", req.getDrawFee());
		reqMap.put("tradeRate", req.getTradeRate());
		Map<String,String> dataMap = new HashMap<String,String>();
		String resStr = "";
		try {
			byte[] encrypt = AESUtil.encryptAES(JsonUtils.mapToJson(reqMap).getBytes(), JftConfigure.AES_KEY.getBytes(), true, "UTF-8");
			String linkString = MD5Utils.createLinkString(reqMap);
			String sign = MD5Util.encrypt(linkString+"&md5key="+JftConfigure.MD5_KEY, "UTF-8");
			//请求
			dataMap.put("orgCode", JftConfigure.ORG_CODE);
			dataMap.put("encryptData", new String(encrypt,"UTF-8"));
			dataMap.put("signData", sign);
			resStr = HttpUtils.post(JftConfigure.BASE_URL+"/fusionPosp/interface/rateModify", dataMap);
		} catch (Exception e) {
			throw new BusException(ResultEnum.UNKONW_EXCEPTION,key);
		}
		logger.info("resStr="+resStr);
		if(Strings.isNullOrEmpty(resStr)){
			throw new BusException("channel.unknow.exception","未知异常");
		}
		JSONObject jsonObject = JSON.parseObject(resStr);
		if(jsonObject.containsKey("resCode")&& !"0000".equals(jsonObject.getString("resCode"))){
			String resCode = jsonObject.getString("resCode");
			String resMsg = jsonObject.getString("resMsg");
//			mchBusService.update(bus.getId(), 2, resCode, resMsg);
			logger.info("渠道响应：resCode={}|resMsg={}",resCode,resMsg);
			throw new BusException(ResultEnum.CHANNEL_RESPONSE_ERROR, resMsg,key);
		}
		JSONObject resObject = null;
		String encryptData = jsonObject.getString("encryptData");
		try {
			byte[] resDate = AESUtil.decryptAES(encryptData.getBytes(), JftConfigure.AES_KEY.getBytes(), true, "UTF-8");
			resObject = JSON.parseObject(new String(resDate,"UTF-8"));
		} catch (Exception e) {
			throw new BusException(ResultEnum.UNKONW_EXCEPTION,key);
		}
		logger.info("resObject="+resObject.toJSONString());
		String resCode = resObject.getString("resCode");
		String resMsg = resObject.getString("resMsg");
		if("0000".equals(resCode)){
			bus.setDrawFee(new BigDecimal(req.getDrawFee()));
			bus.setTradeRate(new BigDecimal(req.getTradeRate()));
			bus.setStatus(1);
			bus.setResCode(resCode);
			bus.setResMsg(resMsg);
			mchBusService.updateById(bus);
		}
		response.setChMerCode(bus.getChMerCode());
		response.setRespCode(resCode);
		response.setRespMsg(resMsg);	
		try {
			response.setSign(MD5Utils.getSign(ObjectUtils.Obj2Map(response), key));
		} catch (Exception e) {
			throw new BusException(ResultEnum.UNKONW_EXCEPTION,key);
		}
		return response;
	}

	@Override
	public Object bankCardModify(Map<String, String> params) {
		ApiMemberRegRsponse response = new ApiMemberRegRsponse();
		ApiBankCardModifyRequest req = new Gson().fromJson(JsonUtils.mapToJson(params), ApiBankCardModifyRequest.class);
		MchInfo mch = mchInfoService.findByMchNo(req.getMchNo());
		if(mch==null){
			throw new BusException(ResultEnum.MCH_UNREGISTER,"");
		}
		String key = mch.getMd5Key();
		
		Result ret = FluentValidator.checkAll()
				.on(req, new HibernateSupportedValidator<ApiBankCardModifyRequest>().setHiberanteValidator(validator))
				.on(params, signVerifyValidator) // 验签
				.doValidate().result(toSimple());
		if (!ret.isSuccess()) {
			String msg = ret.getErrors().get(0);
			throw new BusException(ResultEnum.ERROR_VALIDATE, msg,key);
		}
		//商户信息获取
		MchReg mchReg = mchRegService.findByChMerCode(req.getChMerCode());
		if(mchReg==null){
			throw new BusException(ResultEnum.MCH_UNAPPLICATION,key);
		}
		Map<String,String> mchMap = new HashMap<String,String>();
		mchMap.put("verCode", "1001");
		mchMap.put("chMerCode", req.getChMerCode());
		mchMap.put("accountName", req.getAccountName());
		mchMap.put("accountNo", req.getAccountNo());
		mchMap.put("reservedMobile", req.getReservedMobile());
		if(!Strings.isNullOrEmpty(req.getBankName())){
			mchMap.put("bankName", req.getBankName());
		}
		if(!Strings.isNullOrEmpty(req.getBankCode())){
			mchMap.put("bankCode", req.getBankCode());
		}
		if(!Strings.isNullOrEmpty(req.getOpenProvince())){
			mchMap.put("openProvince", req.getOpenProvince());
		}
		if(!Strings.isNullOrEmpty(req.getOpenCity())){
			mchMap.put("openCity", req.getOpenCity());
		}
		mchMap.put("subBankCode", req.getSubBankCode());
		Map<String,String> dataMap = new HashMap<String,String>();
		String resStr = "";
		try {
			String linkString = MD5Utils.createLinkString(mchMap); 
			String sign = MD5Util.encrypt(linkString+"&md5key="+JftConfigure.MD5_KEY, "UTF-8");
			byte[] encrypt = AESUtil.encryptAES(JsonUtils.mapToJson(mchMap).getBytes(), JftConfigure.AES_KEY.getBytes(), true, "UTF-8");
			dataMap.put("orgCode", JftConfigure.ORG_CODE);
			dataMap.put("encryptData", new String(encrypt,"UTF-8"));
			dataMap.put("signData", sign);
			resStr = HttpUtils.post(JftConfigure.BASE_URL+"/fusionPosp/interface/bankCardModify", dataMap);
		} catch (Exception e) {
			throw new BusException(ResultEnum.UNKONW_EXCEPTION,key);
		}
		logger.info("resStr="+resStr);
		if(Strings.isNullOrEmpty(resStr)){
			throw new BusException("channel.exception","渠道异常");
		}
		JSONObject jsonObject = JSON.parseObject(resStr);
		if(jsonObject.containsKey("resCode")&& !"0000".equals(jsonObject.getString("resCode"))){
			String resCode = jsonObject.getString("resCode");
			String resMsg = jsonObject.getString("resMsg");
			logger.info("渠道响应：resCode={}|resMsg={}",resCode,resMsg);
			throw new BusException(ResultEnum.CHANNEL_RESPONSE_ERROR, resMsg,key);
		}
		JSONObject resObject = null;
		String encryptData = jsonObject.getString("encryptData");
		try {
			byte[] resDate = AESUtil.decryptAES(encryptData.getBytes(), JftConfigure.AES_KEY.getBytes(), true, "UTF-8");
			resObject = JSON.parseObject(new String(resDate,"UTF-8"));
		} catch (Exception e) {
			throw new BusException(ResultEnum.UNKONW_EXCEPTION,key);
		}
		logger.info("resObject="+resObject.toJSONString());
		String resCode = resObject.getString("resCode");
		String resMsg = resObject.getString("resMsg");
		if("0000".equals(resCode)){
			mchReg.setAccountName(req.getAccountName());
			mchReg.setAccountNo(req.getAccountNo());
			mchReg.setReservedMobile(req.getReservedMobile());
			mchReg.setBankCode(req.getBankCode());	
			mchReg.setBankName(req.getBankName());
			mchReg.setOpenCity(req.getOpenCity());
			mchReg.setOpenProvince(req.getOpenProvince());
			mchReg.setSubBankCode(req.getSubBankCode());
			mchReg.setStatus(1);
			mchReg.setResCode(resCode);
			mchReg.setResMsg(resMsg);
			mchRegService.updateById(mchReg);
			response.setChMerCode(resObject.getString("chMerCode"));
		}else{
			mchReg.setStatus(2);
			mchReg.setResCode(resCode);
			mchReg.setResMsg(resMsg);
			mchRegService.update(mchReg.getId(), 2, resCode, resMsg);
		}
		response.setRespCode(resCode);
		response.setRespMsg(resMsg);
		try {
			response.setSign(MD5Utils.getSign(ObjectUtils.Obj2Map(response), key));
		} catch (Exception e) {
			throw new BusException(ResultEnum.UNKONW_EXCEPTION,key);
		}
		return response;
	}

	@Override
	public Object query(Map<String, String> params) {
		ApiQuickPayQueryRsponse res =new ApiQuickPayQueryRsponse();
		ApiJftPayQueryRequest req = new Gson().fromJson(JsonUtils.mapToJson(params), ApiJftPayQueryRequest.class);
		MchInfo mch = mchInfoService.findByMchNo(req.getMchNo());
		if(mch==null){
			throw new BusException("empty.mch", "商户尚未注册");
		}
		String key = mch.getMd5Key();
		
		Result ret = FluentValidator.checkAll()
				.on(req, new HibernateSupportedValidator<ApiJftPayQueryRequest>().setHiberanteValidator(validator))
				.on(params, signVerifyValidator) // 验签
				.doValidate().result(toSimple());
		if (!ret.isSuccess()) {
			String msg = ret.getErrors().get(0);
			throw new BusException(ResultEnum.ERROR_VALIDATE, msg,key);
		}
		if(Strings.isNullOrEmpty(req.getPlatOrderCode())&& Strings.isNullOrEmpty(req.getOrderCode())){
			throw new BusException(ResultEnum.PARAMS_ERROR,key);
		}
		Trans trans = null;
		if(!Strings.isNullOrEmpty(req.getPlatOrderCode())){
			trans = transService.findByPlatOrderCode(req.getPlatOrderCode());
		}else{
			trans = transService.findByOrderCode(req.getOrderCode());
		}
		if(trans==null){
			throw new BusException(ResultEnum.ORDER_NOT_EXIST,key);
		}
		//请求参数封装
		Map<String,String> queryMap = new HashMap<String,String>();
		queryMap.put("verCode", "1001");
		queryMap.put("chMerCode", trans.getChMerCode());
		queryMap.put("orderCode", trans.getPlatOrderCode());
	
		Map<String,String> dataMap = new HashMap<String,String>();
		String resStr = "";
		try {
			String linkString = MD5Utils.createLinkString(queryMap); 
			String sign = MD5Util.encrypt(linkString+"&md5key="+JftConfigure.MD5_KEY, "UTF-8");
			byte[] encrypt = AESUtil.encryptAES(JsonUtils.mapToJson(queryMap).getBytes(), JftConfigure.AES_KEY.getBytes(), true, "UTF-8");
			//请求
			dataMap.put("orgCode",JftConfigure.ORG_CODE);
			dataMap.put("encryptData", new String(encrypt,"UTF-8"));
			dataMap.put("signData", sign);
			resStr = HttpUtils.post(JftConfigure.BASE_URL+"/fusionPosp/interface/tradeQuery", dataMap);
		} catch (Exception e1) {
			e1.printStackTrace();
		}
		logger.info("resStr="+resStr);
		if(Strings.isNullOrEmpty(resStr)){
			throw new BusException(ResultEnum.CHANNEL_RESPONSE_ERROR,key);
		}
		JSONObject jsonObject = JSON.parseObject(resStr);
		if(jsonObject.containsKey("resCode")&& !"0000".equals(jsonObject.getString("resCode"))){
			throw new BusException(jsonObject.getString("resCode"), jsonObject.getString("resMsg"));
		}
		String encryptData = jsonObject.getString("encryptData");
		byte[] resDate = null;
		try {
			resDate = AESUtil.decryptAES(encryptData.getBytes(), JftConfigure.AES_KEY.getBytes(), true, "UTF-8");
		} catch (Exception e) {
			throw new BusException(ResultEnum.UNKONW_EXCEPTION,key);
		}
		JSONObject resObject = null;
		try {
			resObject = JSON.parseObject(new String(resDate,"UTF-8"));
		} catch (UnsupportedEncodingException e) {
			throw new BusException(ResultEnum.UNKONW_EXCEPTION,key);
		}
		logger.info("resObject="+resObject.toJSONString());
		
		String resCode = resObject.getString("resCode");
		res.setRespCode(resCode);
		res.setChMerCode(req.getChMerCode());
		res.setOrderCode(trans.getOrderCode());
		res.setPlatOrderCode(trans.getPlatOrderCode());
		res.setTranAmount(resObject.getString("tranAmount"));
		res.setRealName(resObject.getString("realName"));
		res.setAccNo(resObject.getString("accNo"));
		res.setTranTime(resObject.getString("tranTime"));
		res.setChSerialNo(resObject.getString("chSerialNo"));
		res.setTranStatus(resObject.getString("tranStatus"));
		res.setDrawStatus(resObject.getString("drawStatus"));
		res.setDrawAmount(resObject.getString("drawAmount"));
		try {
			res.setSign(MD5Utils.getSign(ObjectUtils.Obj2Map(res), key));
		} catch (Exception e) {
			throw new BusException(ResultEnum.UNKONW_EXCEPTION,key);
		}
		return res;
	}
	

	@Override
	public ApiNotifyRsponse notify(JSONObject resObject, Trans trans) {
		String tranTime = resObject.getString("tranTime");
		String chSerialNo = resObject.getString("chSerialNo");
		String tranStatus= resObject.getString("tranStatus");
		if("0".equals(tranStatus) && trans.getTranStatus()!=0){
			Trans update = new Trans();
			update.setId(trans.getId());
			update.setChSerialNo(chSerialNo);
			update.setTranTime(tranTime);
			update.setTranStatus(Integer.parseInt(tranStatus));
			transService.updateById(update);
			logger.info("订单"+trans.getPlatOrderCode()+"成功处理");
			//账户资金处理
		}else if(trans.getTranStatus()!=Integer.parseInt(tranStatus)){
			Trans update = new Trans();
			update.setId(trans.getId());
			update.setTranStatus(Integer.parseInt(tranStatus));
			transService.updateById(update);
		}
		ApiNotifyRsponse res = new ApiNotifyRsponse();
		res.setChMerCode(resObject.getString("chMerCode"));
		res.setOrderCode(trans.getOrderCode());
		res.setPlatOrderCode(resObject.getString("orderCode"));
		res.setTranAmount(resObject.getString("tranAmount"));
		res.setTranTime(tranTime);
		res.setChSerialNo(chSerialNo);
		res.setTranStatus(tranStatus);
		return res;
	}

	

}
